package co.yixiang.hw.rest;

import cn.hutool.http.HttpRequest;
import co.yixiang.aop.log.Log;
import co.yixiang.exception.BadRequestException;
import co.yixiang.hw.domain.YxStoreCouponUser;
import co.yixiang.hw.domain.YxStoreOrder;
import co.yixiang.hw.domain.YxStoreOrderCartInfo;
import co.yixiang.hw.domain.YxStoreProduct;
import co.yixiang.hw.service.*;
import co.yixiang.hw.service.dto.YxStoreOrderDto;
import co.yixiang.hw.service.dto.YxStoreOrderQueryCriteria;
import co.yixiang.hw.service.dto.YxStoreProductDto;
import co.yixiang.utils.OrderUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author Walert
* @date 2020-02-13
*/
@Api(tags = "订单接口API管理")
@Slf4j
@RestController
@RequestMapping("/api/yxStoreOrder")
public class YxStoreOrderController extends BaseController {

    private final YxStoreOrderService yxStoreOrderService;
    private final YxStoreOrderCartInfoService yxStoreOrderCartInfoService;
    private final YxStoreProductService yxStoreProductService;
    private final YxStoreOrderStatusService yxStoreOrderStatusService;
    private final YxStoreCartService yxStoreCartService;
    private final YxStoreCouponUserService couponUserService;


    public YxStoreOrderController(YxStoreOrderService yxStoreOrderService,
                                  YxStoreOrderCartInfoService yxStoreOrderCartInfoService,
                                  YxStoreOrderStatusService yxStoreOrderStatusService,
                                  YxStoreProductService yxStoreProductService,
                                  YxStoreCartService yxStoreCartService,
                                  YxStoreCouponUserService couponUserService) {
        this.yxStoreOrderService = yxStoreOrderService;
        this.yxStoreOrderCartInfoService  = yxStoreOrderCartInfoService;
        this.yxStoreProductService  = yxStoreProductService;
        this.yxStoreOrderStatusService  = yxStoreOrderStatusService;
        this.yxStoreCartService  = yxStoreCartService;
        this.couponUserService  = couponUserService;

    }


    @GetMapping
    @Log("查询订单接口API")
    @ApiOperation(value = "查询订单接口API",response = YxStoreOrderDto.class)
    public ResponseEntity<Object> getYxStoreOrders(YxStoreOrderQueryCriteria criteria, Pageable pageable){
        criteria.setUid(getUserId().intValue());
        return new ResponseEntity<>(yxStoreOrderService.queryAll(criteria,pageable),HttpStatus.OK);
    }

    @Log("新增订单接口API")
    @ApiOperation(value = "新增订单接口API",response = YxStoreOrderDto.class)
    @ApiParam(name = "params",value = "{\n" +
                    "     \"realName\":\"\",\n" +
                    "\t \"userPhone\":\"\",\n" +
                    "\t \"userAddress\":\"\",\n" +
                    "\t \"goodsList\":[\n" +
                    "\t\t{\n" +
                    "\t\t\t\"cartId\":\"20\",\n" +
                    "\t\t\t\"productId\":\"20\",\n" +
                    "\t\t\t\"cartNum\":\"3\"\n" +
                    "\t\t}\n" +
                    "\t ]\n" +
                    "}")
    @PostMapping(value = "/add")
    public ResponseEntity<Object> create(@RequestBody JSONObject params) throws Exception {

        String openId = params.getString("openId");
        if(StringUtils.isBlank(openId)) throw new BadRequestException("openId不能为空。");

        //检查商品库存，商品状态
        JSONArray goodsList =  params.getJSONArray("goodsList");
        int size = goodsList.size();

        if(size <= 0) throw new BadRequestException("商品不能为空。");
        Integer totalNum = 0;
        Map<Integer,Integer> goodsNumMap = new HashMap();
        List<Integer> gIds = new ArrayList<>(size);
        JSONArray cartIds = new JSONArray(size);

        BigDecimal couponPrice = BigDecimal.ZERO;


        for (int i = 0; i < size; i++) {
            JSONObject goodsObject = goodsList.getJSONObject(i);
            Integer productId = goodsObject.getInteger("productId");
            Integer cartNum = goodsObject.getInteger("cartNum");
            Integer cartId = goodsObject.getInteger("cartId");
            gIds.add(productId);
            totalNum += cartNum;
            goodsNumMap.put(productId,cartNum);
            if(cartId!=null && cartId > 0) cartIds.add(cartId);
            JSONObject coupon = goodsObject.getJSONObject("coupon");
            if(coupon!= null){
                couponPrice = couponPrice.add(coupon.getBigDecimal("couponPrice"));
            }
        }


        //获取商品明细
        List<YxStoreProduct> products = yxStoreProductService.findByIds(gIds);
        //计算订单总价
        BigDecimal totalPrice = BigDecimal.ZERO;
        Map<Integer,List<YxStoreProduct>> supplierProductMap = new HashMap<>();
        for (YxStoreProduct product : products) {
            totalPrice = totalPrice.add(product.getPrice().multiply(new BigDecimal(goodsNumMap.get(product.getId()))));
            Integer supplierId = product.getSupplierId();
            if(supplierProductMap.containsKey(supplierId)){
                List list = supplierProductMap.get(supplierId);
                list.add(product);
                supplierProductMap.put(supplierId,list);
            }else{
                List list = new ArrayList();
                list.add(product);
                supplierProductMap.put(supplierId,list);
            }
        }

        BigDecimal payPrice = totalPrice;
        if(couponPrice.compareTo(BigDecimal.ZERO) == 1){
            payPrice = totalPrice.subtract(couponPrice);
        }

        BigDecimal payFee = payPrice.multiply(new BigDecimal(100));

        String orderSn = OrderUtil.orderSn();
        //获取微信支付信息
        JSONObject payInfo = getWxPayInfo(openId, payFee,orderSn);

        Long addTime = System.currentTimeMillis() / 1000L;
        //订单主表信息创建
        String orderRemark = params.getString("orderRemark");

        YxStoreOrder resources = new YxStoreOrder();
        if(orderRemark != null){
            resources.setMark(orderRemark);
        }

        JSONObject orderUseCoupon = params.getJSONObject("orderUseCoupon");

        if(orderUseCoupon != null) {
            orderUseCoupon.getLong("id");
            BigDecimal price = orderUseCoupon.getBigDecimal("couponPrice");
            resources.setCouponId(orderUseCoupon.getInteger("id"));
            couponPrice = couponPrice.add(price);
        }

        resources.setOrderId(orderSn);
        resources.setUid(getUserId().intValue());
        resources.setRealName(params.getString("realName"));//收货人
        resources.setUserPhone(params.getString("userPhone"));//收货电话
        resources.setUserAddress(params.getString("userAddress"));
        resources.setTotalNum(totalNum);        //商品总共数量
        resources.setTotalPrice(totalPrice);    //商品总价格
        resources.setPaid(0);
        resources.setAddTime(addTime.intValue());
        resources.setStatus(OrderUtil.orderStatus(0,0,0));
        resources.setIsDel(0);
        resources.setFreightPrice(BigDecimal.ZERO);
        resources.setPayPrice(payPrice);
        resources.setRefundStatus(0);
        resources.setTotalPostage(BigDecimal.ZERO);
        resources.setShippingType(1);
        resources.setStatus(0);
        resources.setPayType("weixin");
        resources.setMerId(1565429451);
        resources.setCouponPrice(couponPrice);
        resources.setIsRoot(0);
        if(supplierProductMap.size() > 1){
            resources.setIsRoot(1);
        }

        YxStoreOrderDto order = yxStoreOrderService.create(resources);

        //异步保存订单商品信息
        yxStoreOrderCartInfoService.saveOrderCartInfo(order,goodsList);

        //需要拆单，异步拆单
        if(order.getIsRoot() == 1){
            yxStoreOrderService.createSubOrder(order,goodsList,supplierProductMap);
        }

        //生成订单状态
        yxStoreOrderStatusService.asyncCreate(order.getId(),"cache_key_create_order","订单生成");
        System.out.println("我已经发送状态保存了");
        //删除购物车数据
        if(cartIds.size() > 0) yxStoreCartService.asyncDelCartInfo(cartIds);

        JSONObject result = new JSONObject();
        result.put("orderInfo",order);
        result.put("payInfo",payInfo);
        return new ResponseEntity<>(result,HttpStatus.OK);
    }

    private JSONObject getWxPayInfo(String openId, BigDecimal payFee,String orderId) {
        String url = "https://pms.polywuye.com/oss-gateway/api/wxPay/unifiedOrder";
        JSONObject requestBody = new JSONObject();
        requestBody.put("body","和院好物订单");
        requestBody.put("totalFee",payFee.intValue());
        requestBody.put("tradeType","JSAPI");
        requestBody.put("openId",openId);
        requestBody.put("outTradeNo",orderId);
        requestBody.put("appId","wxf302b7c838a721f7");
        String responseStr = HttpRequest.post(url).body(requestBody.toJSONString()).execute().body();
        JSONObject response = JSONObject.parseObject(responseStr);
        JSONObject payInfo = null;
        String exceptionCode = response.getString("exceptionCode");
        if("0".equals(exceptionCode)) {
            payInfo = response.getJSONObject("bizContent");
        }else{
            throw new BadRequestException("微信支付下单失败。");
        }
        return payInfo;
    }

    private JSONObject checkWxPayInfo(String orderSn){
        String url = "https://pms.polywuye.com/oss-gateway/api/wxPay/orderQuery";
        JSONObject requestBody = new JSONObject();
        requestBody.put("outTradeNo",orderSn);
        requestBody.put("appId","wxf302b7c838a721f7");


        String responseStr = HttpRequest.post(url).body(requestBody.toJSONString()).execute().body();
        JSONObject response = JSONObject.parseObject(responseStr);
        JSONObject payInfo = null;
        String exceptionCode = response.getString("exceptionCode");
        if("0".equals(exceptionCode)) {
            payInfo = response.getJSONObject("bizContent");
        }else{
            throw new BadRequestException("微信支付订单查询失败。");
        }
        return payInfo;
    }

    @Log("订单详情接口")
    @ApiOperation("订单详情接口API")
    @PostMapping(value = "/details")
    public ResponseEntity<Object> details(@RequestBody JSONObject params){
        JSONObject details = yxStoreOrderService.findById(params.getInteger("id"));
        return new ResponseEntity<>(details,HttpStatus.OK);
    }

    @Log("订单详情接口")
    @ApiOperation("订单详情接口API")
    @GetMapping(value = "/{uniqueNo}")
    public ResponseEntity<Object> details(@PathVariable("uniqueNo") String uniqueNo){
        JSONObject details = yxStoreOrderService.findByUniqueNo(uniqueNo);
        return new ResponseEntity<>(details,HttpStatus.OK);
    }

    @Log("订单立即支付接口API")
    @ApiOperation("订单立即支付接口API")
    @ApiParam(name = "params", example = "{\"openId\":\"\",\"orderId\":\"\"}")
    @PostMapping(value = "/payNow")
    public ResponseEntity<Object> payNow(@RequestBody JSONObject params){
        Integer orderId = params.getInteger("orderId");
        String openId = params.getString("openId");
        YxStoreOrder order = yxStoreOrderService.findByIdAndIsDel(orderId);
        BigDecimal payFee = order.getPayPrice().multiply(new BigDecimal(100));
        JSONObject result = new JSONObject();
        JSONObject wxPayInfo = this.getWxPayInfo(openId, payFee, order.getOrderId());
        result.put("orderInfo",order);
        result.put("payInfo",wxPayInfo);
        return new ResponseEntity<>(result,HttpStatus.OK);
    }

    @Log("订单支付成功接口API")
    @ApiOperation("订单支付成功接口API")
    @ApiParam(name = "params", example = "{\"openId\":\"\",\"orderId\":\"\"}")
    @PostMapping(value = "/paySuccess")
    public ResponseEntity<Object> paySuccess(@RequestBody JSONObject params){
        Integer orderId = params.getInteger("orderId");
        YxStoreOrder order = yxStoreOrderService.findByIdAndIsDel(orderId);

        JSONObject payInfo = this.checkWxPayInfo(order.getOrderId());
        if(payInfo != null){
            String transId = payInfo.getString("transaction_id");
            order.setTransId(transId);
            order.setTransInfo(payInfo.toJSONString());
        }
        Long payTime = System.currentTimeMillis()/1000L;
        order.setPaid(1);
        order.setPayTime(payTime.intValue());
        yxStoreOrderService.update(order);
        if(order.getIsRoot() == 1){
            List<YxStoreOrder> subOrders = yxStoreOrderService.getByParentId(order.getId());
            for (YxStoreOrder subOrder : subOrders) {

                subOrder.setPayTime(order.getPayTime());
                subOrder.setPaid(order.getPaid());
                subOrder.setTransId(order.getTransId());
                subOrder.setTransInfo(order.getTransInfo());

                yxStoreOrderService.update(subOrder);
                yxStoreOrderStatusService.asyncCreate(subOrder.getId(),"pay_success","用户付款成功");

            }
        }

        //使用优惠券
        couponUserService.useCouponByOrderId(orderId,order.getOrderId());

        //生成订单状态
        yxStoreOrderStatusService.asyncCreate(order.getId(),"pay_success","用户付款成功");

        return new ResponseEntity<>(HttpStatus.OK);
    }

}